/*
 *  JImageDiffFrame.java
 *
 *  Copyright (C) 2010-2011 Francisco Gómez Carrasco
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  Report bugs or new features to: flikxxi@gmail.com
 *
 */
package com.softenido.findrepe.showgroup;

import com.softenido.cafedark.imageio.ScaleImage;
import com.softenido.cafedark.io.virtual.VirtualFile;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import org.apache.commons.compress.archivers.ArchiveException;

/**
 *
 * @author franci
 */
public class JImageDiffFrame extends javax.swing.JFrame
{

    private VirtualFile[] fileImages = null;
    private boolean[] delete = null;
    final private ImageShowGroup sg;
    private ImageTableModel model;
    final private JTable table;

    /** Creates new form JImageDiffFrame */
    public JImageDiffFrame(ImageShowGroup sg)
    {
        initComponents();
        this.setTitle("findrepe");
        this.sg = sg;
        model = null;
        table = new JTable(model);
        JScrollPane sc = new JScrollPane(table);
        jpnTable.add(sc);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jButtonPanel = new javax.swing.JPanel();
        jbExit = new javax.swing.JButton();
        jbNext = new javax.swing.JButton();
        jbAll = new javax.swing.JButton();
        jbNone = new javax.swing.JButton();
        jpnTable = new javax.swing.JPanel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jbExit.setMnemonic('E');
        jbExit.setText("Exit");
        jbExit.setMaximumSize(null);
        jbExit.setMinimumSize(null);
        jbExit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbExitActionPerformed(evt);
            }
        });

        jbNext.setMnemonic('N');
        jbNext.setText("Next");
        jbNext.setMaximumSize(null);
        jbNext.setMinimumSize(null);
        jbNext.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbNextActionPerformed(evt);
            }
        });

        jbAll.setMnemonic('A');
        jbAll.setText("All");
        jbAll.setMaximumSize(null);
        jbAll.setMinimumSize(null);
        jbAll.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbAllActionPerformed(evt);
            }
        });

        jbNone.setMnemonic('o');
        jbNone.setText("None");
        jbNone.setMaximumSize(null);
        jbNone.setMinimumSize(null);
        jbNone.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbNoneActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jButtonPanelLayout = new javax.swing.GroupLayout(jButtonPanel);
        jButtonPanel.setLayout(jButtonPanelLayout);
        jButtonPanelLayout.setHorizontalGroup(
            jButtonPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jButtonPanelLayout.createSequentialGroup()
                .addContainerGap(154, Short.MAX_VALUE)
                .addComponent(jbAll, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jbNone, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jbNext, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jbExit, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        jButtonPanelLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jbAll, jbExit, jbNext, jbNone});

        jButtonPanelLayout.setVerticalGroup(
            jButtonPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jButtonPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jButtonPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE, false)
                    .addComponent(jbNone, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jbAll, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jbNext, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jbExit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

        jButtonPanelLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {jbAll, jbExit, jbNext, jbNone});

        jpnTable.setLayout(new javax.swing.BoxLayout(jpnTable, javax.swing.BoxLayout.Y_AXIS));

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jButtonPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(jpnTable, javax.swing.GroupLayout.DEFAULT_SIZE, 664, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addComponent(jpnTable, javax.swing.GroupLayout.DEFAULT_SIZE, 402, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jButtonPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jbAllActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jbAllActionPerformed
    {//GEN-HEADEREND:event_jbAllActionPerformed
        for (int i = 0; i < delete.length; i++)
        {
            model.setDelete(i,true);
        }
    }//GEN-LAST:event_jbAllActionPerformed

    private void jbExitActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jbExitActionPerformed
    {//GEN-HEADEREND:event_jbExitActionPerformed
        System.exit(0);
    }//GEN-LAST:event_jbExitActionPerformed

    private void jbNoneActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jbNoneActionPerformed
    {//GEN-HEADEREND:event_jbNoneActionPerformed
        for (int i = 0; i < delete.length; i++)
        {
            model.setDelete(i,false);
        }
    }//GEN-LAST:event_jbNoneActionPerformed

    private void jbNextActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jbNextActionPerformed
    {//GEN-HEADEREND:event_jbNextActionPerformed

        for(int i =0;i<delete.length;i++)
        {
            delete[i] = model.getDelete(i);
        }
        sg.delete(fileImages, delete);
        synchronized (sg)
        {
            sg.notifyAll();
        }
    }//GEN-LAST:event_jbNextActionPerformed

    public void showImages(int groupId, VirtualFile[] files, boolean[] deleted) throws IOException, ArchiveException
    {
        this.fileImages = files;
        this.delete = deleted;

        model = new ImageTableModel(files,delete);
        table.setModel(model);
        table.setRowHeight(Math.max(25,model.getHeight()+2));

        table.getColumnModel().getColumn(0).setMaxWidth(25);
        
        table.getColumnModel().getColumn(1).setMinWidth(model.getWidth());
        table.getColumnModel().getColumn(1).setWidth(model.getWidth()+10);
        table.getColumnModel().getColumn(1).setMaxWidth(model.getWidth()+20);

        table.getColumnModel().getColumn(2).setMaxWidth(50);
        table.getColumnModel().getColumn(3).setMaxWidth(100);
        table.getColumnModel().getColumn(4).setMaxWidth(100);
//        table.getColumnModel().getColumn(5).setMaxWidth(1000);
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel jButtonPanel;
    private javax.swing.JButton jbAll;
    private javax.swing.JButton jbExit;
    private javax.swing.JButton jbNext;
    private javax.swing.JButton jbNone;
    private javax.swing.JPanel jpnTable;
    // End of variables declaration//GEN-END:variables
}

class ImageTableModel extends AbstractTableModel
{
    public static final int DELETE_COLUMN = 2;
    private final VirtualFile[] files;
    private final Object[][] cells;
    static final String[] columnNames ={"Id", "Image", "Delete", "size", "Dimension", "Path"};
    private final ScaleImage sf = new ScaleImage(300, 200, false);

    final private int height;
    final private int width;
    
    public ImageTableModel(VirtualFile[] files,boolean[] delete)
    {
        this.files = files;
        this.cells = new Object[files.length][];

        int w=0;
        int h=0;

        for(int i=0;i<files.length;i++)
        {
            try
            {
                BufferedImage bi = ImageIO.read(files[i].getInputStream());
                bi = sf.filter(bi);
                w = Math.max(w,bi.getWidth());
                h = Math.max(h,bi.getHeight());
                ImageIcon icon = new ImageIcon(bi);
                String dim = "["+bi.getWidth()+" x "+bi.getHeight()+"]";
                this.cells[i] = new Object[]{i,icon,delete[i],files[i].length(),dim,files[i].toString()};
            }
            catch (IOException ex)
            {
                Logger.getLogger(ImageTableModel.class.getName()).log(Level.SEVERE, null, ex);
            }
            catch (ArchiveException ex)
            {
                Logger.getLogger(ImageTableModel.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        this.width = w;
        this.height= h;
    }
    

    @Override
    public String getColumnName(int c)
    {
        return columnNames[c];
    }

    @Override
    public Class<?> getColumnClass(int c)
    {
        return cells[0][c].getClass();
    }

    @Override
    public int getColumnCount()
    {
        return cells[0].length;
    }

    @Override
    public int getRowCount()
    {
        return cells.length;
    }

    @Override
    public Object getValueAt(int r, int c)
    {
        return cells[r][c];
    }

    @Override
    public void setValueAt(Object obj, int r, int c)
    {
        cells[r][c] = obj;
    }

    @Override
    public boolean isCellEditable(int r, int c)
    {
        return (c == DELETE_COLUMN) && files[r].canWrite();
    }

    public int getHeight()
    {
        return height;
    }

    public int getWidth()
    {
        return width;
    }

    void setDelete(int i, boolean b)
    {
        cells[i][DELETE_COLUMN] = b;
        this.fireTableRowsUpdated(i, i);
    }
    boolean getDelete(int i)
    {
        return ((Boolean)cells[i][DELETE_COLUMN]).booleanValue();
    }
    
}
